﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using DevExpress.XtraPrinting.Native;

namespace DevTools.AndroidLayoutHelper
{
    public class LayoutReader
    {
        public static void Read(string filePath, List<string> excludeList, string template1, string template2, out string result1, out string result2)
        {
            List<LayoutElement> list = new List<LayoutElement>();

            using (XmlTextReader reader = new XmlTextReader(filePath))
            {
                while (reader.Read())
                {
                    if (reader.NodeType != XmlNodeType.Element)
                        continue;

                    if (excludeList != null && excludeList.Contains(reader.Name))
                        continue;

                    var id = reader.GetAttribute("android:id");
                    if (string.IsNullOrEmpty(id))
                        continue;

                    list.Add(new LayoutElement(reader.Name, id));
                }
            }

            result1 = Format(template1, list);
            result2 = Format(template2, list);
        }

        private static string Format(string template, List<LayoutElement> list)
        {
            /*
            #region declare widgets
            <% private {0} {1}; %>
            #endregion
             */

            /*
            #region find widgets
            <% {1} = FindViewById<{0}>(Resource.Id.{1}); %>
            #endregion
            */

            Regex regex = new Regex(RegularExpression, RegexOptions.Singleline);
            MatchCollection matches = regex.Matches(template);
            string[] splitedTexts = regex.Split(template);
            splitedTexts = RemoveDirectives(splitedTexts);

            StringBuilder buffer = new StringBuilder();
            for (int i = 0; i < splitedTexts.Length; i++)
            {
                buffer.Append(splitedTexts[i]);

                if (i >= splitedTexts.Length - 1)
                    continue;

                var lines = ExtractLine(matches[i].Value, list);
                lines.ForEach(x => buffer.AppendLine(x));
            }

            return buffer.ToString();
        }

        private const string Directives = "%";

        private const string RegularExpression = @"<%.*?%>";

        #region private methods
        private static List<string> ExtractLine(string text, List<LayoutElement> list)
        {
            string lineTemplate = text.Substring(3, text.Length - 6).Trim();

            List<string> lines = new List<string>();

            foreach (var item in list)
                lines.Add(string.Format(lineTemplate, item.Name, item.Id));
            
            return lines;
        }

        /// <summary>
        /// TACONG- 와 같은 지시어구로만 이루어진 토큰을 삭제한다.
        /// </summary>
        /// <param name="tokens"></param>
        /// <returns></returns>
        private static string[] RemoveDirectives(string[] tokens)
        {
            List<string> result = new List<string>();

            foreach (string token in tokens)
                if (token.Length != 1 || Directives.Contains(token) == false)
                    result.Add(token);

            return result.ToArray();
        }
        #endregion
    }
}
